package com.snack.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.snack.shop.common.BusinessException;
import com.snack.shop.entity.ErrandOrder;
import com.snack.shop.entity.Order;
import com.snack.shop.entity.PickupCategory;
import com.snack.shop.entity.User;
import com.snack.shop.mapper.ErrandOrderMapper;
import com.snack.shop.mapper.OrderMapper;
import com.snack.shop.mapper.PickupCategoryMapper;
import com.snack.shop.mapper.UserMapper;
import com.snack.shop.service.FileManageService;
import com.snack.shop.service.SettlementService;
import com.snack.shop.service.MerchantMessageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 结算服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SettlementServiceImpl implements SettlementService {

    private final OrderMapper orderMapper;
    private final ErrandOrderMapper errandOrderMapper;
    private final PickupCategoryMapper pickupCategoryMapper;
    private final UserMapper userMapper;
    private final FileManageService fileManageService;
    private final MerchantMessageService merchantMessageService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void applySettlement(Long orderId, Long userId, String paymentMethod, String paymentAccount, String paymentQrCode, String paymentPhone, String remark) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }

        if (!order.getDeliveryUserId().equals(userId)) {
            throw new BusinessException("无权操作此订单");
        }

        // 允许待结算(5)和已退款且有补偿金(8)的订单申请结算
        if (order.getStatus() != 5 && !(order.getStatus() == 8 && order.getCompensationAmount() != null && order.getCompensationAmount().compareTo(BigDecimal.ZERO) > 0)) {
            throw new BusinessException("订单状态不正确，无法申请结算");
        }

        if (order.getSettlementStatus() != 0) {
            throw new BusinessException("订单已申请结算");
        }

        // 更新结算状态和收款信息
        order.setSettlementStatus(1); // 申请中
        order.setSettlementApplyTime(LocalDateTime.now());
        order.setPaymentMethod(paymentMethod);
        order.setPaymentAccount(paymentAccount);
        order.setPaymentQrCode(paymentQrCode);
        order.setPaymentPhone(paymentPhone);
        if (remark != null && !remark.trim().isEmpty()) {
            order.setRemark(remark);
        }
        orderMapper.updateById(order);
        
        // 为商家创建消息：待结算订单提醒
        try {
            Long merchantId = getMerchantId();
            if (merchantId != null) {
                merchantMessageService.create(merchantId, 3, "待结算订单", "订单" + order.getOrderNo() + "申请结算，金额¥" + order.getRiderEarning(), "settlement", order.getId());
            }
        } catch (Exception e) {
            log.warn("创建商家消息失败, orderId={}", orderId, e);
        }
        
        // 确认收款码图片为正式状态
        try {
            if (paymentQrCode != null && !paymentQrCode.trim().isEmpty()) {
                fileManageService.confirmFiles(
                    Collections.singletonList(paymentQrCode),
                    "settlement",
                    orderId
                );
                log.info("确认结算收款码为正式状态: orderId={}, qrCode={}", orderId, paymentQrCode);
            }
        } catch (Exception e) {
            log.error("确认结算收款码失败: orderId={}", orderId, e);
            // 不影响主流程
        }
    }

    @Override
    public Map<String, Object> getStatistics(Long userId) {
        // 查询接单总数
        LambdaQueryWrapper<Order> totalWrapper = new LambdaQueryWrapper<>();
        totalWrapper.eq(Order::getDeliveryUserId, userId)
                   .in(Order::getOrderType, 2, 3, 4, 5);
        Long totalOrders = orderMapper.selectCount(totalWrapper);

        // 查询完成订单数（包括已退款但有补偿金的订单）
        LambdaQueryWrapper<Order> completedWrapper = new LambdaQueryWrapper<>();
        completedWrapper.eq(Order::getDeliveryUserId, userId)
                       .in(Order::getOrderType, 2, 3, 4, 5)
                       .and(wrapper -> wrapper.in(Order::getStatus, 5, 6)
                           .or(subWrapper -> subWrapper.eq(Order::getStatus, 8)
                               .isNotNull(Order::getCompensationAmount)
                               .gt(Order::getCompensationAmount, BigDecimal.ZERO)));
        Long completedOrders = orderMapper.selectCount(completedWrapper);

        // 计算完成率
        double completionRate = totalOrders > 0 ? (completedOrders * 100.0 / totalOrders) : 0;

        // 查询所有收益订单（包括已退款但有补偿金的订单）
        LambdaQueryWrapper<Order> earningWrapper = new LambdaQueryWrapper<>();
        earningWrapper.eq(Order::getDeliveryUserId, userId)
                     .in(Order::getOrderType, 2, 3, 4, 5)
                     .and(wrapper -> wrapper.in(Order::getStatus, 5, 6)
                         .or(subWrapper -> subWrapper.eq(Order::getStatus, 8)
                             .isNotNull(Order::getCompensationAmount)
                             .gt(Order::getCompensationAmount, BigDecimal.ZERO)));
        List<Order> earningOrders = orderMapper.selectList(earningWrapper);

        // 计算总收益（防止 NPE）
        BigDecimal totalEarnings = earningOrders.stream()
                .map(o -> o.getRiderEarning() != null ? o.getRiderEarning() : BigDecimal.ZERO)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 计算已结算收益
        BigDecimal settledEarnings = earningOrders.stream()
                .filter(o -> o.getSettlementStatus() == 2)
                .map(o -> o.getRiderEarning() != null ? o.getRiderEarning() : BigDecimal.ZERO)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 计算未结算收益
        BigDecimal unsettledEarnings = earningOrders.stream()
                .filter(o -> o.getSettlementStatus() == 0)
                .map(o -> o.getRiderEarning() != null ? o.getRiderEarning() : BigDecimal.ZERO)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 计算申请中收益
        BigDecimal applyingEarnings = earningOrders.stream()
                .filter(o -> o.getSettlementStatus() == 1)
                .map(o -> o.getRiderEarning() != null ? o.getRiderEarning() : BigDecimal.ZERO)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        Map<String, Object> stats = new HashMap<>();
        stats.put("totalEarnings", totalEarnings);
        stats.put("settledEarnings", settledEarnings);
        stats.put("unsettledEarnings", unsettledEarnings);
        stats.put("applyingEarnings", applyingEarnings);
        stats.put("totalOrders", totalOrders);
        stats.put("completedOrders", completedOrders);
        stats.put("completionRate", String.format("%.0f", completionRate));

        return stats;
    }

    @Override
    public Page<Map<String, Object>> getRecords(Long userId, Integer settlementStatus, Integer current, Integer size) {
        Page<Order> page = new Page<>(current, size);
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(Order::getDeliveryUserId, userId)
               .in(Order::getOrderType, 2, 3, 4, 5)
               .and(w -> w.in(Order::getStatus, 5, 6)
                   .or(subWrapper -> subWrapper.eq(Order::getStatus, 8)
                       .isNotNull(Order::getCompensationAmount)
                       .gt(Order::getCompensationAmount, BigDecimal.ZERO))); // 包括已退款但有补偿金的订单

        if (settlementStatus != null) {
            wrapper.eq(Order::getSettlementStatus, settlementStatus);
        }

        wrapper.orderByDesc(Order::getCreateTime);

        Page<Order> orderPage = orderMapper.selectPage(page, wrapper);

        Page<Map<String, Object>> resultPage = new Page<>(current, size);
        resultPage.setTotal(orderPage.getTotal());
        resultPage.setRecords(orderPage.getRecords().stream().map(this::buildSettlementMap).collect(Collectors.toList()));

        return resultPage;
    }

    @Override
    public Map<String, Object> getSettlementInfo(Long orderId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }

        if (order.getSettlementStatus() != 1) {
            throw new BusinessException("订单未申请结算或已处理");
        }

        Map<String, Object> info = new HashMap<>();
        
        // 基本订单信息
        info.put("id", order.getId());
        info.put("orderNo", order.getOrderNo());
        info.put("orderType", order.getOrderType());
        
        // 接单人信息（通过deliveryUserId查询）
        if (order.getDeliveryUserId() != null) {
            User deliveryUser = userMapper.selectById(order.getDeliveryUserId());
            if (deliveryUser != null) {
                info.put("deliveryUserName", deliveryUser.getNickname());
                info.put("deliveryUserPhone", deliveryUser.getPhone());
            }
        }
        
        // 结算金额信息
        info.put("actualAmount", order.getActualAmount());
        info.put("platformFee", order.getPlatformFee());
        info.put("platformFeeRate", order.getPlatformFeeRate());
        info.put("riderEarning", order.getRiderEarning());
        
        // 收款信息（用户申请结算时填写的）
        info.put("paymentMethod", order.getPaymentMethod());
        info.put("paymentAccount", order.getPaymentAccount());
        info.put("paymentQrCode", order.getPaymentQrCode());
        info.put("paymentPhone", order.getPaymentPhone());
        info.put("remark", order.getRemark());
        
        // 时间信息
        info.put("confirmTime", order.getConfirmTime());
        info.put("settlementApplyTime", order.getSettlementApplyTime());
        info.put("settlementStatus", order.getSettlementStatus());
        
        // 分类信息（代取订单才有category_id）
        // 订单类型2/3/4/5是代取订单，需要从errand_order表获取categoryId
        if (order.getOrderType() != null && (order.getOrderType() == 2 || order.getOrderType() == 3 || order.getOrderType() == 4 || order.getOrderType() == 5)) {
            ErrandOrder errandOrder = errandOrderMapper.selectOne(
                new LambdaQueryWrapper<ErrandOrder>().eq(ErrandOrder::getOrderId, order.getId())
            );
            if (errandOrder != null && errandOrder.getCategoryId() != null) {
                PickupCategory category = pickupCategoryMapper.selectById(errandOrder.getCategoryId());
                if (category != null) {
                    info.put("categoryName", category.getName());
                }
            }
        }
        
        return info;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void settleOrder(Long orderId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }

        // 允许待结算(5)和已退款且有补偿金(8)的订单进行结算
        if (order.getStatus() != 5 && !(order.getStatus() == 8 && order.getCompensationAmount() != null && order.getCompensationAmount().compareTo(BigDecimal.ZERO) > 0)) {
            throw new BusinessException("订单状态不正确，无法结算");
        }

        if (order.getSettlementStatus() == 2) {
            throw new BusinessException("订单已结算");
        }

        // 更新订单状态
        order.setSettlementStatus(2); // 已结算
        order.setSettlementTime(LocalDateTime.now());
        
        // 只有正常订单才改为已完成状态，退款订单保持退款状态
        if (order.getStatus() == 5) {
            order.setStatus(6); // 待结算 -> 已完成
            order.setFinishTime(LocalDateTime.now());
        }
        // 退款订单(status=8)保持不变，只更新结算状态
        
        orderMapper.updateById(order);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approveSettlement(Long orderId, Boolean approved, String remark) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }

        if (order.getSettlementStatus() != 1) {
            throw new BusinessException("订单未申请结算或已处理");
        }

        if (approved) {
            // 审核通过
            order.setSettlementStatus(2); // 已结算
            order.setSettlementTime(LocalDateTime.now());
            order.setStatus(6); // 已完成
        } else {
            // 审核不通过
            order.setSettlementStatus(0); // 退回未结算
            order.setSettlementApplyTime(null);
        }

        orderMapper.updateById(order);
    }

    @Override
    public Page<Map<String, Object>> getPendingList(Integer current, Integer size) {
        Page<Order> page = new Page<>(current, size);
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();

        wrapper.in(Order::getOrderType, 2, 3, 4, 5)
               .eq(Order::getSettlementStatus, 1) // 申请中
               .orderByAsc(Order::getSettlementApplyTime);

        Page<Order> orderPage = orderMapper.selectPage(page, wrapper);

        Page<Map<String, Object>> resultPage = new Page<>(current, size);
        resultPage.setTotal(orderPage.getTotal());
        resultPage.setRecords(orderPage.getRecords().stream().map(this::buildSettlementMap).collect(Collectors.toList()));

        return resultPage;
    }

    /**
     * 构建结算记录Map
     */
    private Map<String, Object> buildSettlementMap(Order order) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", order.getId());
        map.put("orderNo", order.getOrderNo());
        map.put("status", order.getStatus()); // 订单状态，用于前端判断是否为退款订单
        map.put("totalAmount", order.getTotalAmount());
        map.put("actualAmount", order.getActualAmount()); // 实际金额
        map.put("platformFee", order.getPlatformFee());
        map.put("platformFeeRate", order.getPlatformFeeRate());
        map.put("riderEarning", order.getRiderEarning());
        map.put("compensationAmount", order.getCompensationAmount()); // 补偿金额
        map.put("settlementStatus", order.getSettlementStatus());
        map.put("settlementStatusText", getSettlementStatusText(order.getSettlementStatus()));
        map.put("settlementApplyTime", order.getSettlementApplyTime());
        map.put("settlementTime", order.getSettlementTime());
        map.put("finishTime", order.getFinishTime());
        map.put("confirmTime", order.getConfirmTime()); // 确认时间
        map.put("createTime", order.getCreateTime());

        // 查询跑腿订单详情
        LambdaQueryWrapper<ErrandOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ErrandOrder::getOrderId, order.getId());
        ErrandOrder errandOrder = errandOrderMapper.selectOne(wrapper);
        if (errandOrder != null && errandOrder.getCategoryId() != null) {
            PickupCategory category = pickupCategoryMapper.selectById(errandOrder.getCategoryId());
            if (category != null) {
                map.put("categoryName", category.getName());
            }
        }

        return map;
    }

    /**
     * 获取结算状态文本
     */
    private String getSettlementStatusText(Integer status) {
        switch (status) {
            case 0: return "未结算";
            case 1: return "申请中";
            case 2: return "已结算";
            default: return "未知";
        }
    }

    /**
     * 获取商家ID（单商户模式：查询 user_type=3 的用户）
     */
    private Long getMerchantId() {
        try {
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getUserType, 3) // user_type=3 为商家
                   .last("limit 1");
            User merchant = userMapper.selectOne(wrapper);
            return merchant != null ? merchant.getId() : null;
        } catch (Exception e) {
            log.error("获取商家ID失败", e);
            return null;
        }
    }
}

